package com.declum.archon.chunkserver.manager.disk.chunk;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import com.declum.archon.chunkserver.manager.disk.streams.ChunkInputStream;
import com.declum.archon.chunkserver.manager.disk.streams.ChunkOutputStream;

/**
 * This Class holds the information about Chunks in the Chunk Server.
 * 
 * @author Clement
 * 
 */
public class ChunkInfo {
	public static int	ALIVE		= 0;
	public static int	DEAD		= -1;
	public static int	INPROGRESS	= 1;

	private String		chunkHome;
	private String		chunkid;
	private String		chunkPath;
	private String		parentPath;
	boolean				resolved;

	private int			status;

	public static ChunkInfo getInstance(String chunkid, String parentPath) {
		if ((chunkid == null) || (parentPath == null)) {
			throw new NullPointerException("Args cannot be Null");
		}
		ChunkInfo chunkInfo = new ChunkInfo();
		chunkInfo.chunkid = chunkid;
		chunkInfo.resolved = false;
		chunkInfo.parentPath = parentPath;
		chunkInfo.chunkHome = chunkInfo.parentPath + File.separator + chunkid
				+ File.separator;
		chunkInfo.chunkPath = chunkInfo.chunkHome + File.separator + chunkid
				+ ".chunk";
		return chunkInfo;
	}

	public void create() throws Exception {
		this.createChunkHome();
		this.createChunkFile();
		this.resolved = true;
	}

	private void createChunkFile() throws IOException {
		File file = new File(this.chunkPath);
		if (!file.exists()) {
			file.createNewFile();
		}
		this.chunkPath = file.getAbsolutePath();
	}

	private void createChunkHome() throws IOException {
		File dir = new File(this.chunkHome);
		if (!dir.exists()) {
			dir.mkdirs();
		}
		this.chunkHome = dir.getAbsolutePath();

	}

	public InputStream createInputStream() throws Exception {
		return this.createInputStream(ChunkInputStream.NORMAL_MODE);
	}

	public InputStream createInputStream(int mode) throws Exception {
		this.resolveIfNotCreate();
		InputStream in = new ChunkInputStream(this.chunkPath, mode);
		return in;
	}

	public OutputStream createOutputStream() throws Exception {
		return this.createOutputStream(false);
	}

	public OutputStream createOutputStream(boolean append) throws Exception {
		this.resolveIfNotCreate();
		OutputStream out = new ChunkOutputStream(this.chunkPath, append);
		return out;
	}

	public String getChunkid() {
		return this.chunkid;
	}

	public int getStatus() {
		return this.status;
	}

	public boolean isResolved() {
		return this.resolved;
	}

	public void resolve() throws Exception {
		if (this.resolved) {
			return;
		}
		File file = new File(this.chunkPath);
		if (!file.exists()) {
			throw new FileNotFoundException(this.chunkPath + " does not exists");
		}
		this.chunkPath = file.getAbsolutePath();
		this.resolved = true;
	}

	void resolveIfNotCreate() throws Exception {
		if (!this.isResolved()) {
			try {
				this.resolve();
			} catch (FileNotFoundException e) {
				this.create();
			}
		}
	}

	public void setStatus(int status) {
		this.status = status;
	}
}
